/*
Copyright (C) 2006 - 2014 Evan Teran
                          eteran@alum.rit.edu

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef OPTABLE_2BYTE_20080314_TCC_
#define OPTABLE_2BYTE_20080314_TCC_

namespace edisassm {

template <class M>
const typename Instruction<M>::opcode_entry Instruction<M>::Opcodes_2Byte_NA[0x100] = {

	/* 0x0f 0x00 - 0x0f 0x0f */
	{ "group6",  &Instruction::decode_group6,  OP_GROUP,   FLAG_NONE },
	{ "group7",  &Instruction::decode_group7,  OP_GROUP,   FLAG_NONE },
	{ "lar",     &Instruction::decode_Gv_Ew,   OP_LAR,     FLAG_W_FLAGS },
	{ "lsl",     &Instruction::decode_Gv_Ew,   OP_LSL,     FLAG_W_FLAGS },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "clts",    &Instruction::decode0,        OP_CLTS,    FLAG_RING0 },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invd",    &Instruction::decode0,        OP_INVD,    FLAG_NONE },
	{ "wbinvd",  &Instruction::decode0,        OP_WBINVD,  FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "ud2",     &Instruction::decode0,        OP_UD2,     FLAG_PENTIUM_PRO },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "nop",     &Instruction::decode_Ev,      OP_NOP,     FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },

	/* 0x0f 0x10 - 0x0f 0x1f */
	{ "movups",   &Instruction::decode_Vo_Wo,   OP_MOVUPS,   FLAG_SSE },
	{ "movups",   &Instruction::decode_Wo_Vo,   OP_MOVUPS,   FLAG_SSE },
	{ "movlps",   &Instruction::decode_Vq_Mq,   OP_MOVLPS,   FLAG_SSE }, // TODO: movhlps here too
	{ "movlps",   &Instruction::decode_Mq_Vq,   OP_MOVLPS,   FLAG_SSE },
	{ "unpcklps", &Instruction::decode_Vo_Wq,   OP_UNPCKLPS, FLAG_SSE },
	{ "unpckhps", &Instruction::decode_Vo_Wq,   OP_UNPCKHPS, FLAG_SSE },
	{ "movhps",   &Instruction::decode_Vq_Mq,   OP_MOVHPS,   FLAG_SSE },  // TODO: movlhps here too
	{ "movhps",   &Instruction::decode_Mq_Vq,   OP_MOVHPS,   FLAG_SSE },
	{ "group17",  &Instruction::decode_group17, OP_GROUP,    FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid, OP_INVALID,  FLAG_NONE },
	{ "nop",      &Instruction::decode_Ev,      OP_NOP,      FLAG_NONE }, // undocumented
	{ "invalid",  &Instruction::decode_invalid, OP_INVALID,  FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid, OP_INVALID,  FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid, OP_INVALID,  FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid, OP_INVALID,  FLAG_NONE },
	{ "nop",      &Instruction::decode_Ev,      OP_NOP,      FLAG_NONE },

	/* 0x0f 0x20 - 0x0f 0x2f */
	{ "mov",       &Instruction::decode_Rd_Cd,   OP_MOV,       FLAG_R_FLAGS },
	{ "mov",       &Instruction::decode_Rd_Dd,   OP_MOV,       FLAG_R_FLAGS },
	{ "mov",       &Instruction::decode_Cd_Rd,   OP_MOV,       FLAG_R_FLAGS },
	{ "mov",       &Instruction::decode_Dd_Rd,   OP_MOV,       FLAG_R_FLAGS },
	{ "invalid",   &Instruction::decode_invalid, OP_INVALID,   FLAG_NONE },
	{ "invalid",   &Instruction::decode_invalid, OP_INVALID,   FLAG_NONE },
	{ "invalid",   &Instruction::decode_invalid, OP_INVALID,   FLAG_NONE },
	{ "invalid",   &Instruction::decode_invalid, OP_INVALID,   FLAG_NONE },
	{ "movaps",    &Instruction::decode_Vo_Wo,   OP_MOVAPS,    FLAG_SSE },
	{ "movaps",    &Instruction::decode_Wo_Vo,   OP_MOVAPS,    FLAG_SSE },
	{ "cvtpi2ps",  &Instruction::decode_Vo_Qq,   OP_CVTPI2PS,  FLAG_SSE },
	{ "movntps",   &Instruction::decode_Mo_Vo,   OP_MOVNTPS,   FLAG_SSE },
	{ "cvttps2pi", &Instruction::decode_Pq_Wo,   OP_CVTTPS2PI, FLAG_SSE },
	{ "cvtps2pi",  &Instruction::decode_Pq_Wo,   OP_CVTPS2PI,  FLAG_SSE },
	{ "ucomiss",   &Instruction::decode_Vo_Wo,   OP_UCOMISS,   FLAG_SSE | FLAG_W_FLAGS },
	{ "comiss",    &Instruction::decode_Vo_Wo,   OP_COMISS,    FLAG_SSE | FLAG_W_FLAGS },

	/* 0x0f 0x30 - 0x0f 0x3f */
	{ "wrmsr",    &Instruction::decode0,         OP_WRMSR,    FLAG_NONE },
	{ "rdtsc",    &Instruction::decode0,         OP_RDTSC,    FLAG_NONE },
	{ "rdmsr",    &Instruction::decode0,         OP_RDMSR,    FLAG_NONE },
	{ "rdpmc",    &Instruction::decode0,         OP_RDPMC,    FLAG_NONE },
	{ "sysenter", &Instruction::decode0,         OP_SYSENTER, FLAG_PENTIUM_PRO | FLAG_W_FLAGS },
	{ "sysexit",  &Instruction::decode0,         OP_SYSEXIT,  FLAG_PENTIUM_PRO | FLAG_W_FLAGS },
	{ "invalid",  &Instruction::decode_invalid,  OP_INVALID,  FLAG_NONE },
	{ "getsec",   &Instruction::decode0,         OP_GETSEC,   FLAG_NONE },
	{ "3byte",    &Instruction::decode_3byte_38, OP_3BYTE,    FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid,  OP_INVALID,  FLAG_NONE },
	{ "3byte",    &Instruction::decode_3byte_3A, OP_3BYTE,    FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid,  OP_INVALID,  FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid,  OP_INVALID,  FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid,  OP_INVALID,  FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid,  OP_INVALID,  FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid,  OP_INVALID,  FLAG_NONE },

	/* 0x0f 0x40 - 0x0f 0x4f */
	{ "cmovo",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovno",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovb",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnb",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovz",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnz",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovb",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnbe", &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovs",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovns",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovp",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnp",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovl",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnl",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovle",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnle", &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },

	/* 0x0f 0x50 - 0x0f 0x5f */
	{ "movmskps", &Instruction::decode_Gd_Uo, OP_MOVMSKPS, FLAG_SSE }, // x86-64: movmskps Gq, Uo
	{ "sqrtps",   &Instruction::decode_Vo_Wo, OP_SQRTPS,   FLAG_SSE },
	{ "rsqrtps",  &Instruction::decode_Vo_Wo, OP_RSQRTPS,  FLAG_SSE },
	{ "rcpps",    &Instruction::decode_Vo_Wo, OP_RCPPS,    FLAG_SSE },
	{ "andps",    &Instruction::decode_Vo_Wo, OP_ANDPS,    FLAG_SSE },
	{ "andnps",   &Instruction::decode_Vo_Wo, OP_ANDNPS,   FLAG_SSE },
	{ "orps",     &Instruction::decode_Vo_Wo, OP_ORPS,     FLAG_SSE },
	{ "xorps",    &Instruction::decode_Vo_Wo, OP_XORPS,    FLAG_SSE },
	{ "addps",    &Instruction::decode_Vo_Wo, OP_ADDPS,    FLAG_SSE },
	{ "mulps",    &Instruction::decode_Vo_Wo, OP_MULPS,    FLAG_SSE },
	{ "cvtps2pd", &Instruction::decode_Vo_Wo, OP_CVTPS2PD, FLAG_SSE2 },
	{ "cvtdq2ps", &Instruction::decode_Vo_Wo, OP_CVTDQ2PS, FLAG_SSE2 },
	{ "subps",    &Instruction::decode_Vo_Wo, OP_SUBPS,    FLAG_SSE },
	{ "minps",    &Instruction::decode_Vo_Wo, OP_MINPS,    FLAG_SSE },
	{ "divps",    &Instruction::decode_Vo_Wo, OP_DIVPS,    FLAG_SSE },
	{ "maxps",    &Instruction::decode_Vo_Wo, OP_MAXPS,    FLAG_SSE },

	/* 0x0f 0x60 - 0x0f 0x6f */
	{ "punpcklbw", &Instruction::decode_Pq_Qd,   OP_PUNPCKLBW, FLAG_MMX },
	{ "punpcklwd", &Instruction::decode_Pq_Qd,   OP_PUNPCKLWD, FLAG_MMX },
	{ "punpckldq", &Instruction::decode_Pq_Qd,   OP_PUNPCKLDQ, FLAG_MMX },
	{ "packsswb",  &Instruction::decode_Pq_Qq,   OP_PACKSSWB,  FLAG_MMX },
	{ "pcmpgtb",   &Instruction::decode_Pq_Qq,   OP_PCMPGTB,   FLAG_MMX },
	{ "pcmpgtw",   &Instruction::decode_Pq_Qq,   OP_PCMPGTW,   FLAG_MMX },
	{ "pcmpgtd",   &Instruction::decode_Pq_Qq,   OP_PCMPGTD,   FLAG_MMX },
	{ "packuswb",  &Instruction::decode_Pq_Qq,   OP_PACKUSWB,  FLAG_MMX },
	{ "punpckhbw", &Instruction::decode_Pq_Qd,   OP_PUNPCKHBW, FLAG_MMX },
	{ "punpckhwd", &Instruction::decode_Pq_Qd,   OP_PUNPCKHWD, FLAG_MMX },
	{ "punpckhdq", &Instruction::decode_Pq_Qd,   OP_PUNPCKHDQ, FLAG_MMX },
	{ "packssdw",  &Instruction::decode_Pq_Qq,   OP_PACKSSDW,  FLAG_MMX },
	{ "invalid",   &Instruction::decode_invalid, OP_INVALID,   FLAG_NONE },
	{ "invalid",   &Instruction::decode_invalid, OP_INVALID,   FLAG_NONE },
	{ "movd",      &Instruction::decode_Pd_Ed,   OP_MOVD,      FLAG_MMX }, // x86-64: movq Pd, Eq
	{ "movq",      &Instruction::decode_Pq_Qq,   OP_MOVQ,      FLAG_MMX },

	/* 0x0f 0x70 - 0x0f 0x7f */
	{ "pshufw",  &Instruction::decode_Pq_Qq_Ib, OP_PSHUFW,  FLAG_SSE },
	{ "group13", &Instruction::decode_group13,  OP_GROUP,   FLAG_NONE },
	{ "group14", &Instruction::decode_group14,  OP_GROUP,   FLAG_NONE },
	{ "group15", &Instruction::decode_group15,  OP_GROUP,   FLAG_NONE },
	{ "pcmpeqb", &Instruction::decode_Pq_Qq,    OP_PCMPEQB, FLAG_MMX },
	{ "pcmpeqw", &Instruction::decode_Pq_Qq,    OP_PCMPEQW, FLAG_MMX },
	{ "pcmpeqd", &Instruction::decode_Pq_Qq,    OP_PCMPEQD, FLAG_MMX },
	{ "emms",    &Instruction::decode0,         OP_EMMS,    FLAG_MMX },
	{ "vmread",  &Instruction::decode_Ed_Gd,    OP_VMREAD,  FLAG_VMX | FLAG_W_FLAGS }, // x86-64: vmread Eq, Gq
	{ "vmwrite", &Instruction::decode_Gd_Ed,    OP_VMWRITE, FLAG_VMX | FLAG_W_FLAGS }, // x86-64: vmwrite Gq, Eq
	{ "invalid", &Instruction::decode_invalid,  OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid,  OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid,  OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid,  OP_INVALID, FLAG_NONE },
	{ "movd",    &Instruction::decode_Ed_Pd,    OP_MOVD,    FLAG_MMX }, // x86-64: movq Eq,Pd
	{ "movq",    &Instruction::decode_Qq_Pq,    OP_MOVQ,    FLAG_MMX },

	/* 0x0f 0x80 - 0x0f 0x8f */
	{ "jo",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jno",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jb",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnb",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jz",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnz",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jbe",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnbe", &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "js",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jns",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jp",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnp",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jl",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnl",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jle",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnle", &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },

	/* 0x0f 0x90 - 0x0f 0x9f */
	{ "seto",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setno",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setb",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnb",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setz",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnz",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setbe",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnbe", &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "sets",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setns",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setp",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnp",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setl",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnl",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setle",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnle", &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },

	/* 0x0f 0xa0 - 0x0f 0xaf */
	{ "push",    &Instruction::decode_SegFS,    OP_PUSH,    FLAG_STACK },
	{ "pop",     &Instruction::decode_SegFS,    OP_POP,     FLAG_STACK },
	{ "cpuid",   &Instruction::decode0,         OP_CPUID,   FLAG_NONE },
	{ "bt",      &Instruction::decode_Ev_Gv,    OP_BT,      FLAG_W_FLAGS },
	{ "shld",    &Instruction::decode_Ev_Gv_Ib, OP_SHLD,    FLAG_NONE },
	{ "shld",    &Instruction::decode_Ev_Gv_CL, OP_SHLD,    FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid,  OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid,  OP_INVALID, FLAG_NONE },
	{ "push",    &Instruction::decode_SegGS,    OP_PUSH,    FLAG_STACK },
	{ "pop",     &Instruction::decode_SegGS,    OP_POP,     FLAG_STACK },
	{ "rsm",     &Instruction::decode0,         OP_RSM,     FLAG_NONE },
	{ "bts",     &Instruction::decode_Ev_Gv,    OP_BTS,     FLAG_W_FLAGS },
	{ "shrd",    &Instruction::decode_Ev_Gv_Ib, OP_SHRD,    FLAG_NONE },
	{ "shrd",    &Instruction::decode_Ev_Gv_CL, OP_SHRD,    FLAG_NONE },
	{ "group16", &Instruction::decode_group16,  OP_GROUP,   FLAG_NONE },
	{ "imul",    &Instruction::decode_Gv_Ev,    OP_IMUL,    FLAG_W_FLAGS },

	/* 0x0f 0xb0 - 0x0f 0xbf */
	{ "cmpxchg", &Instruction::decode_Eb_Gb,   OP_CMPXCHG, FLAG_W_FLAGS },
	{ "cmpxchg", &Instruction::decode_Ev_Gv,   OP_CMPXCHG, FLAG_W_FLAGS },
	{ "lss",     &Instruction::decode_Gv_Mp,   OP_LSS,     FLAG_NONE },
	{ "btr",     &Instruction::decode_Ev_Gv,   OP_BTR,     FLAG_W_FLAGS },
	{ "lfs",     &Instruction::decode_Gv_Mp,   OP_LFS,     FLAG_NONE },
	{ "lgs",     &Instruction::decode_Gv_Mp,   OP_LGS,     FLAG_NONE },
	{ "movzx",   &Instruction::decode_Gv_Eb,   OP_MOVZX,   FLAG_NONE },
	{ "movzx",   &Instruction::decode_Gv_Ew,   OP_MOVZX,   FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "group11", &Instruction::decode_group11, OP_GROUP,   FLAG_NONE },
	{ "group8",  &Instruction::decode_group8,  OP_GROUP,   FLAG_NONE },
	{ "btc",     &Instruction::decode_Ev_Gv,   OP_BTC,     FLAG_W_FLAGS },
	{ "bsf",     &Instruction::decode_Gv_Ev,   OP_BSF,     FLAG_W_FLAGS },
	{ "bsr",     &Instruction::decode_Gv_Ev,   OP_BSR,     FLAG_W_FLAGS },
	{ "movsx",   &Instruction::decode_Gv_Eb,   OP_MOVSX,   FLAG_NONE },
	{ "movsx",   &Instruction::decode_Gv_Ew,   OP_MOVSX,   FLAG_NONE },

	/* 0x0f 0xc0 - 0x0f 0xcf */
	{ "xadd",   &Instruction::decode_Eb_Gb,       OP_XADD,   FLAG_NONE },
	{ "xadd",   &Instruction::decode_Ev_Gv,       OP_XADD,   FLAG_NONE },
	{ "cmpps",  &Instruction::decode_Vo_Wo_Ib,    OP_CMPPS,  FLAG_SSE },
	{ "movnti", &Instruction::decode_Md_Gd,       OP_MOVNTI, FLAG_SSE2 }, // x86-64: movnti Nq, Gq
	{ "pinsrw", &Instruction::decode_Pq_Rd_Mw_Ib, OP_PINSRW, FLAG_SSE }, // x86-64: pinsrw Pq, Rq/Mw,Ib
	{ "pextrw", &Instruction::decode_Gd_Nq_Ib,    OP_PEXTRW, FLAG_SSE | FLAG_SSE4_1 },
	{ "shufps", &Instruction::decode_Vo_Wo_Ib,    OP_SHUFPS, FLAG_SSE },
	{ "group9", &Instruction::decode_group9,      OP_GROUP,  FLAG_NONE },
	{ "bswap",  &Instruction::decode_rAX,         OP_BSWAP,  FLAG_NONE },
	{ "bswap",  &Instruction::decode_rCX,         OP_BSWAP,  FLAG_NONE },
	{ "bswap",  &Instruction::decode_rDX,         OP_BSWAP,  FLAG_NONE },
	{ "bswap",  &Instruction::decode_rBX,         OP_BSWAP,  FLAG_NONE },
	{ "bswap",  &Instruction::decode_rSP,         OP_BSWAP,  FLAG_NONE },
	{ "bswap",  &Instruction::decode_rBP,         OP_BSWAP,  FLAG_NONE },
	{ "bswap",  &Instruction::decode_rSI,         OP_BSWAP,  FLAG_NONE },
	{ "bswap",  &Instruction::decode_rDI,         OP_BSWAP,  FLAG_NONE },

	/* 0x0f 0xd0 - 0x0f 0xdf */
	{ "invalid",  &Instruction::decode_invalid, OP_INVALID,  FLAG_NONE },
	{ "psrlw",    &Instruction::decode_Pq_Qq,   OP_PSRLW,    FLAG_MMX },
	{ "psrld",    &Instruction::decode_Pq_Qq,   OP_PSRLD,    FLAG_NONE },
	{ "psrlq",    &Instruction::decode_Pq_Qq,   OP_PSRLQ,    FLAG_MMX },
	{ "paddq",    &Instruction::decode_Pq_Qq,   OP_PADDQ,    FLAG_SSE2 },
	{ "pmullw",   &Instruction::decode_Pq_Qq,   OP_PMULLW,   FLAG_MMX },
	{ "invalid",  &Instruction::decode_invalid, OP_INVALID,  FLAG_NONE },
	{ "pmovmskb", &Instruction::decode_Gd_Nq,   OP_PMOVMSKB, FLAG_SSE },
    { "psubusb",  &Instruction::decode_Pq_Qq,   OP_PSUBUSB,  FLAG_MMX },
    { "psubusw",  &Instruction::decode_Pq_Qq,   OP_PSUBUSW,  FLAG_MMX },
    { "pminub",   &Instruction::decode_Pq_Qq,   OP_PMINUB,   FLAG_SSE },
    { "pand",     &Instruction::decode_Pq_Qq,   OP_PAND,     FLAG_MMX },
    { "paddusb",  &Instruction::decode_Pq_Qq,   OP_PADDUSB,  FLAG_MMX },
    { "paddusw",  &Instruction::decode_Pq_Qq,   OP_PADDUSW,  FLAG_MMX },
    { "pmaxub",   &Instruction::decode_Pq_Qq,   OP_PMAXUB,   FLAG_SSE },
    { "pandn",    &Instruction::decode_Pq_Qq,   OP_PANDN,    FLAG_MMX },

	/* 0x0f 0xe0 - 0x0f 0xef */
	{ "pavgb",   &Instruction::decode_Pq_Qq,   OP_PAVGB,   FLAG_SSE },
	{ "psraw",   &Instruction::decode_Pq_Qq,   OP_PSRAW,   FLAG_MMX },
	{ "psrad",   &Instruction::decode_Pq_Qq,   OP_PSRAD,   FLAG_MMX },
	{ "pavgw",   &Instruction::decode_Pq_Qq,   OP_PAVGW,   FLAG_SSE },
	{ "pmulhuw", &Instruction::decode_Pq_Qq,   OP_PMULHUW, FLAG_SSE },
	{ "pmulhw",  &Instruction::decode_Pq_Qq,   OP_PMULHW,  FLAG_MMX },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "movntq",  &Instruction::decode_Mq_Pq,   OP_MOVNTQ,  FLAG_SSE },
	{ "psubsb",  &Instruction::decode_Pq_Qq,   OP_PSUBSB,  FLAG_MMX },
	{ "psubsw",  &Instruction::decode_Pq_Qq,   OP_PSUBSW,  FLAG_MMX },
	{ "pminsw",  &Instruction::decode_Pq_Qq,   OP_PMINSW,  FLAG_SSE },
	{ "por",     &Instruction::decode_Pq_Qq,   OP_POR,     FLAG_MMX },
	{ "paddsb",  &Instruction::decode_Pq_Qq,   OP_PADDSB,  FLAG_MMX },
	{ "paddsw",  &Instruction::decode_Pq_Qq,   OP_PADDSW,  FLAG_MMX },
	{ "pmaxsw",  &Instruction::decode_Pq_Qq,   OP_PMAXSW,  FLAG_SSE },
	{ "pxor",    &Instruction::decode_Pq_Qq,   OP_PXOR,    FLAG_MMX },

	/* 0x0f 0xf0 - 0x0f 0xff */
	{ "invalid",  &Instruction::decode_invalid, OP_INVALID,  FLAG_NONE },
	{ "psllw",    &Instruction::decode_Pq_Qq,   OP_PSLLW,    FLAG_MMX },
	{ "pslld",    &Instruction::decode_Pq_Qq,   OP_PSLLD,    FLAG_MMX },
	{ "psllq",    &Instruction::decode_Pq_Qq,   OP_PSLLQ,    FLAG_MMX },
	{ "pmuludq",  &Instruction::decode_Pq_Qq,   OP_PMULUDQ,  FLAG_SSE2 },
	{ "pmaddwd",  &Instruction::decode_Pq_Qq,   OP_PMADDWD,  FLAG_MMX },
	{ "psadbw",   &Instruction::decode_Pq_Qq,   OP_PSADBW,   FLAG_SSE },
	{ "maskmovq", &Instruction::decode_Pq_Nq,   OP_MASKMOVQ, FLAG_SSE },
	{ "psubb",    &Instruction::decode_Pq_Qq,   OP_PSUBB,    FLAG_MMX },
	{ "psubw",    &Instruction::decode_Pq_Qq,   OP_PSUBW,    FLAG_MMX },
	{ "psubd",    &Instruction::decode_Pq_Qq,   OP_PSUBD,    FLAG_MMX },
	{ "psubq",    &Instruction::decode_Pq_Qq,   OP_PSUBQ,    FLAG_SSE2 },
	{ "paddb",    &Instruction::decode_Pq_Qq,   OP_PADDB,    FLAG_MMX },
	{ "paddw",    &Instruction::decode_Pq_Qq,   OP_PADDW,    FLAG_MMX },
	{ "paddd",    &Instruction::decode_Pq_Qq,   OP_PADDD,    FLAG_MMX },
	{ "invalid",  &Instruction::decode_invalid, OP_INVALID,  FLAG_NONE },
};


// 2 byte opcodes with a 66 prefix
template <class M>
const typename Instruction<M>::opcode_entry Instruction<M>::Opcodes_2Byte_66[0x100] = {

	/* 0x0f 0x00 - 0x0f 0x0f */
	{ "group6",  &Instruction::decode_group6,  OP_GROUP,   FLAG_NONE },
	{ "group7",  &Instruction::decode_group7,  OP_GROUP,   FLAG_NONE },
	{ "lar",     &Instruction::decode_Gv_Ew,   OP_LAR,     FLAG_W_FLAGS },
	{ "lsl",     &Instruction::decode_Gv_Ew,   OP_LSL,     FLAG_W_FLAGS },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "clts",    &Instruction::decode0,        OP_CLTS,    FLAG_W_FLAGS },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invd",    &Instruction::decode0,        OP_INVD,    FLAG_NONE },
	{ "wbinvd",  &Instruction::decode0,        OP_WBINVD,  FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "ud2",     &Instruction::decode0,        OP_UD2,     FLAG_PENTIUM_PRO },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "nop",     &Instruction::decode_Ev,      OP_NOP,     FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },

	/* 0x0f 0x10 - 0x0f 0x1f */
	{ "movupd",   &Instruction::decode_Vo_Wo,   OP_MOVUPD,   FLAG_SSE2 },
	{ "movupd",   &Instruction::decode_Wo_Vo,   OP_MOVUPD,   FLAG_SSE2 },
	{ "movlpd",   &Instruction::decode_Vq_Mq,   OP_MOVLPD,   FLAG_SSE2 },
	{ "movlpd",   &Instruction::decode_Mq_Vq,   OP_MOVLPD,   FLAG_SSE2 },
	{ "unpcklpd", &Instruction::decode_Vo_Wq,   OP_UNPCKLPD, FLAG_SSE2 },
	{ "unpckhpd", &Instruction::decode_Vo_Wq,   OP_UNPCKHPD, FLAG_SSE2 },
	{ "movhpd",   &Instruction::decode_Vq_Mq,   OP_MOVHPD,   FLAG_SSE2 },
	{ "movhpd",   &Instruction::decode_Mq_Vq,   OP_MOVHPD,   FLAG_SSE2 },
	{ "group17",  &Instruction::decode_group17, OP_GROUP,    FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid, OP_INVALID,  FLAG_NONE },
	{ "nop",      &Instruction::decode_Ev,      OP_NOP,      FLAG_NONE }, // undocumented
	{ "invalid",  &Instruction::decode_invalid, OP_INVALID,  FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid, OP_INVALID,  FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid, OP_INVALID,  FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid, OP_INVALID,  FLAG_NONE },
	{ "nop",      &Instruction::decode_Ev,      OP_NOP,      FLAG_NONE },

	/* 0x0f 0x20 - 0x0f 0x2f */
	{ "mov",       &Instruction::decode_Rd_Cd,   OP_MOV,       FLAG_R_FLAGS },
	{ "mov",       &Instruction::decode_Rd_Dd,   OP_MOV,       FLAG_R_FLAGS },
	{ "mov",       &Instruction::decode_Cd_Rd,   OP_MOV,       FLAG_R_FLAGS },
	{ "mov",       &Instruction::decode_Dd_Rd,   OP_MOV,       FLAG_R_FLAGS },
	{ "invalid",   &Instruction::decode_invalid, OP_INVALID,   FLAG_NONE },
	{ "invalid",   &Instruction::decode_invalid, OP_INVALID,   FLAG_NONE },
	{ "invalid",   &Instruction::decode_invalid, OP_INVALID,   FLAG_NONE },
	{ "invalid",   &Instruction::decode_invalid, OP_INVALID,   FLAG_NONE },
	{ "movapd",    &Instruction::decode_Vo_Wo,   OP_MOVAPD,    FLAG_SSE2 },
	{ "movapd",    &Instruction::decode_Wo_Vo,   OP_MOVAPD,    FLAG_SSE2 },
	{ "cvtpi2pd",  &Instruction::decode_Vo_Qq,   OP_CVTPI2PD,  FLAG_SSE2 },
	{ "movntpd",   &Instruction::decode_Mo_Vo,   OP_MOVNTPD,   FLAG_SSE2 },
	{ "cvttpd2pi", &Instruction::decode_Pq_Wo,   OP_CVTTPD2PI, FLAG_SSE2 },
	{ "cvtpd2pi",  &Instruction::decode_Qq_Wo,   OP_CVTPD2PI,  FLAG_SSE2 },
	{ "ucomisd",   &Instruction::decode_Vo_Wo,   OP_UCOMISD,   FLAG_SSE2 },
	{ "comisd",    &Instruction::decode_Vo_Wo,   OP_COMISD,    FLAG_SSE2 | FLAG_W_FLAGS },

	/* 0x0f 0x30 - 0x0f 0x3f */
	{ "wrmsr",    &Instruction::decode0,         OP_WRMSR,    FLAG_NONE },
	{ "rdtsc",    &Instruction::decode0,         OP_RDTSC,    FLAG_NONE },
	{ "rdmsr",    &Instruction::decode0,         OP_RDMSR,    FLAG_NONE },
	{ "rdpmc",    &Instruction::decode0,         OP_RDPMC,    FLAG_NONE },
	{ "sysenter", &Instruction::decode0,         OP_SYSENTER, FLAG_PENTIUM_PRO | FLAG_W_FLAGS },
	{ "sysexit",  &Instruction::decode0,         OP_SYSEXIT,  FLAG_PENTIUM_PRO | FLAG_W_FLAGS },
	{ "invalid",  &Instruction::decode_invalid,  OP_INVALID,  FLAG_NONE },
	{ "getsec",   &Instruction::decode0,         OP_GETSEC,   FLAG_NONE },
	{ "3byte",    &Instruction::decode_3byte_38, OP_3BYTE,    FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid,  OP_INVALID,  FLAG_NONE },
	{ "3byte",    &Instruction::decode_3byte_3A, OP_3BYTE,    FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid,  OP_INVALID,  FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid,  OP_INVALID,  FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid,  OP_INVALID,  FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid,  OP_INVALID,  FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid,  OP_INVALID,  FLAG_NONE },

	/* 0x0f 0x40 - 0x0f 0x4f */
	{ "cmovo",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovno",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovb",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnb",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovz",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnz",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovb",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnbe", &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovs",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovns",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovp",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnp",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovl",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnl",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovle",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnle", &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },

	/* 0x0f 0x50 - 0x0f 0x5f */
	{ "movmskpd", &Instruction::decode_Gd_Uo, OP_MOVMSKPD, FLAG_SSE2 }, // x86-64: movmskpd Gq, Uo
	{ "sqrtpd",   &Instruction::decode_Vo_Wo, OP_SQRTPD,   FLAG_SSE2 },
	{ "rsqrtps",  &Instruction::decode_Vo_Wo, OP_RSQRTPS,  FLAG_SSE },
	{ "rcpps",    &Instruction::decode_Vo_Wo, OP_RCPPS,    FLAG_SSE },
	{ "andpd",    &Instruction::decode_Vo_Wo, OP_ANDPD,    FLAG_SSE2 },
	{ "andnpd",   &Instruction::decode_Vo_Wo, OP_ANDNPD,   FLAG_SSE2 },
	{ "orpd",     &Instruction::decode_Vo_Wo, OP_ORPD,     FLAG_SSE2 },
	{ "xorpd",    &Instruction::decode_Vo_Wo, OP_XORPD,    FLAG_SSE2 },
	{ "addpd",    &Instruction::decode_Vo_Wo, OP_ADDPD,    FLAG_SSE2 },
	{ "mulpd",    &Instruction::decode_Vo_Wo, OP_MULPD,    FLAG_SSE2 },
	{ "cvtpd2ps", &Instruction::decode_Vo_Wo, OP_CVTPD2PS, FLAG_SSE2 },
	{ "cvtps2dq", &Instruction::decode_Vo_Wo, OP_CVTPS2DQ, FLAG_SSE2 },
	{ "subpd",    &Instruction::decode_Vo_Wo, OP_SUBPD,    FLAG_SSE2 },
	{ "minpd",    &Instruction::decode_Vo_Wo, OP_MINPD,    FLAG_SSE2 },
	{ "divpd",    &Instruction::decode_Vo_Wo, OP_DIVPD,    FLAG_SSE2 },
	{ "maxpd",    &Instruction::decode_Vo_Wo, OP_MAXPD,    FLAG_SSE2 },

	/* 0x0f 0x60 - 0x0f 0x6f */
	{ "punpcklbw",  &Instruction::decode_Vo_Wo, OP_PUNPCKLBW,  FLAG_MMX },
	{ "punpcklwd",  &Instruction::decode_Vo_Wo, OP_PUNPCKLWD,  FLAG_MMX },
	{ "punpckldq",  &Instruction::decode_Vo_Wo, OP_PUNPCKLDQ,  FLAG_MMX },
	{ "packsswb",   &Instruction::decode_Vo_Wo, OP_PACKSSWB,   FLAG_MMX },
	{ "pcmpgtb",    &Instruction::decode_Vo_Wo, OP_PCMPGTB,    FLAG_MMX },
	{ "pcmpgtw",    &Instruction::decode_Vo_Wo, OP_PCMPGTW,    FLAG_MMX },
	{ "pcmpgtd",    &Instruction::decode_Vo_Wo, OP_PCMPGTD,    FLAG_MMX },
	{ "packuswb",   &Instruction::decode_Vo_Wo, OP_PACKUSWB,   FLAG_MMX },
	{ "punpckhbw",  &Instruction::decode_Vo_Wo, OP_PUNPCKHBW,  FLAG_MMX },
	{ "punpckhwd",  &Instruction::decode_Vo_Wo, OP_PUNPCKHWD,  FLAG_MMX },
	{ "punpckhdq",  &Instruction::decode_Vo_Wo, OP_PUNPCKHDQ,  FLAG_MMX },
	{ "packssdw",   &Instruction::decode_Vo_Wo, OP_PACKSSDW,   FLAG_MMX },
	{ "punpcklqdq", &Instruction::decode_Vo_Wo, OP_PUNPCKLQDQ, FLAG_SSE2 },
	{ "punpckhqdq", &Instruction::decode_Vo_Wo, OP_PUNPCKHQDQ, FLAG_SSE2 },
	{ "movd",       &Instruction::decode_Vo_Ed, OP_MOVD,       FLAG_MMX }, // x86-64: movq Vo, Eq
	{ "movq",       &Instruction::decode_Vo_Qq, OP_MOVQ,       FLAG_MMX },

	/* 0x0f 0x70 - 0x0f 0x7f */
	{ "pshufd",  &Instruction::decode_Vo_Wo_Ib, OP_PSHUFD,  FLAG_SSE2 },
	{ "group13", &Instruction::decode_group13,  OP_GROUP,   FLAG_NONE },
	{ "group14", &Instruction::decode_group14,  OP_GROUP,   FLAG_NONE },
	{ "group15", &Instruction::decode_group15,  OP_GROUP,   FLAG_NONE },
	{ "pcmpeqb", &Instruction::decode_Vo_Wo,    OP_PCMPEQB, FLAG_MMX },
	{ "pcmpeqw", &Instruction::decode_Vo_Wo,    OP_PCMPEQW, FLAG_MMX },
	{ "pcmpeqd", &Instruction::decode_Vo_Wo,    OP_PCMPEQD, FLAG_MMX },
	{ "emms",    &Instruction::decode0,         OP_EMMS,    FLAG_MMX },
	{ "vmread",  &Instruction::decode_Ed_Gd,    OP_VMREAD,  FLAG_VMX | FLAG_W_FLAGS }, // x86-64: vmread Eq, Gq
	{ "vmwrite", &Instruction::decode_Gd_Ed,    OP_VMWRITE, FLAG_VMX | FLAG_W_FLAGS }, // x86-64: vmwrite Gq, Eq
	{ "invalid", &Instruction::decode_invalid,  OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid,  OP_INVALID, FLAG_NONE },
	{ "haddpd",  &Instruction::decode_Vo_Wo,    OP_HADDPD,  FLAG_SSE3 },
	{ "hsubpd",  &Instruction::decode_Vo_Wo,    OP_HSUBPD,  FLAG_SSE3 },
	{ "movd",    &Instruction::decode_Ed_Vo,    OP_MOVD,    FLAG_MMX }, // x86-64: movq Eq, Vo
	{ "movdqa",  &Instruction::decode_Wo_Vo,    OP_MOVDQA,  FLAG_SSE2 },

	/* 0x0f 0x80 - 0x0f 0x8f */
	{ "jo",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jno",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jb",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnb",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jz",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnz",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jbe",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnbe", &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "js",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jns",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jp",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnp",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jl",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnl",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jle",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnle", &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },

	/* 0x0f 0x90 - 0x0f 0x9f */
	{ "seto",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setno",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setb",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnb",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setz",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnz",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setbe",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnbe", &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "sets",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setns",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setp",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnp",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setl",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnl",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setle",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnle", &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },

	/* 0x0f 0xa0 - 0x0f 0xaf */
	{ "push",    &Instruction::decode_SegFS,    OP_PUSH,    FLAG_STACK },
	{ "pop",     &Instruction::decode_SegFS,    OP_POP,     FLAG_STACK },
	{ "cpuid",   &Instruction::decode0,         OP_CPUID,   FLAG_NONE },
	{ "bt",      &Instruction::decode_Ev_Gv,    OP_BT,      FLAG_W_FLAGS },
	{ "shld",    &Instruction::decode_Ev_Gv_Ib, OP_SHLD,    FLAG_NONE },
	{ "shld",    &Instruction::decode_Ev_Gv_CL, OP_SHLD,    FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid,  OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid,  OP_INVALID, FLAG_NONE },
	{ "push",    &Instruction::decode_SegGS,    OP_PUSH,    FLAG_STACK },
	{ "pop",     &Instruction::decode_SegGS,    OP_POP,     FLAG_STACK },
	{ "rsm",     &Instruction::decode0,         OP_RSM,     FLAG_NONE },
	{ "bts",     &Instruction::decode_Ev_Gv,    OP_BTS,     FLAG_W_FLAGS },
	{ "shrd",    &Instruction::decode_Ev_Gv_Ib, OP_SHRD,    FLAG_NONE },
	{ "shrd",    &Instruction::decode_Ev_Gv_CL, OP_SHRD,    FLAG_NONE },
	{ "group16", &Instruction::decode_group16,  OP_GROUP,   FLAG_NONE },
	{ "imul",    &Instruction::decode_Gv_Ev,    OP_IMUL,    FLAG_W_FLAGS },

	/* 0x0f 0xb0 - 0x0f 0xbf */
	{ "cmpxchg", &Instruction::decode_Eb_Gb,   OP_CMPXCHG, FLAG_W_FLAGS },
	{ "cmpxchg", &Instruction::decode_Ev_Gv,   OP_CMPXCHG, FLAG_W_FLAGS },
	{ "lss",     &Instruction::decode_Gv_Mp,   OP_LSS,     FLAG_NONE },
	{ "btr",     &Instruction::decode_Ev_Gv,   OP_BTR,     FLAG_W_FLAGS },
	{ "lfs",     &Instruction::decode_Gv_Mp,   OP_LFS,     FLAG_NONE },
	{ "lgs",     &Instruction::decode_Gv_Mp,   OP_LGS,     FLAG_NONE },
	{ "movzx",   &Instruction::decode_Gv_Eb,   OP_MOVZX,   FLAG_NONE },
	{ "movzx",   &Instruction::decode_Gv_Ew,   OP_MOVZX,   FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "group11", &Instruction::decode_group11, OP_GROUP,   FLAG_NONE },
	{ "group8",  &Instruction::decode_group8,  OP_GROUP,   FLAG_NONE },
	{ "btc",     &Instruction::decode_Ev_Gv,   OP_BTC,     FLAG_W_FLAGS },
	{ "bsf",     &Instruction::decode_Gv_Ev,   OP_BSF,     FLAG_W_FLAGS },
	{ "bsr",     &Instruction::decode_Gv_Ev,   OP_BSR,     FLAG_W_FLAGS },
	{ "movsx",   &Instruction::decode_Gv_Eb,   OP_MOVSX,   FLAG_NONE },
	{ "movsx",   &Instruction::decode_Gv_Ew,   OP_MOVSX,   FLAG_NONE },

	/* 0x0f 0xc0 - 0x0f 0xcf */
	{ "xadd",   &Instruction::decode_Eb_Gb,       OP_XADD,   FLAG_NONE },
	{ "xadd",   &Instruction::decode_Ev_Gv,       OP_XADD,   FLAG_NONE },
	{ "cmppd",  &Instruction::decode_Vo_Wo_Ib,    OP_CMPPD,  FLAG_SSE2 },
	{ "movnti", &Instruction::decode_Md_Gd,       OP_MOVNTI, FLAG_SSE2 }, // x86-64: movnti Nq, Gq
	{ "pinsrw", &Instruction::decode_Vo_Rd_Mw_Ib, OP_PINSRW, FLAG_SSE },  // x86-64: pinsrw Vo, Rq/Mw,Ib
	{ "pextrw", &Instruction::decode_Gd_Uo_Ib,    OP_PEXTRW, FLAG_SSE | FLAG_SSE4_1 },
	{ "shufpd", &Instruction::decode_Vo_Wo_Ib,    OP_SHUFPD, FLAG_SSE2 },
	{ "group9", &Instruction::decode_group9,      OP_GROUP,  FLAG_NONE },
	{ "bswap",  &Instruction::decode_rAX,         OP_BSWAP,  FLAG_NONE },
	{ "bswap",  &Instruction::decode_rCX,         OP_BSWAP,  FLAG_NONE },
	{ "bswap",  &Instruction::decode_rDX,         OP_BSWAP,  FLAG_NONE },
	{ "bswap",  &Instruction::decode_rBX,         OP_BSWAP,  FLAG_NONE },
	{ "bswap",  &Instruction::decode_rSP,         OP_BSWAP,  FLAG_NONE },
	{ "bswap",  &Instruction::decode_rBP,         OP_BSWAP,  FLAG_NONE },
	{ "bswap",  &Instruction::decode_rSI,         OP_BSWAP,  FLAG_NONE },
	{ "bswap",  &Instruction::decode_rDI,         OP_BSWAP,  FLAG_NONE },

	/* 0x0f 0xd0 - 0x0f 0xdf */
	{ "addsubpd",&Instruction::decode_Vo_Wo, OP_ADDSUBPD, FLAG_SSE3 },
	{ "psrlw",   &Instruction::decode_Vo_Wo, OP_PSRLW,    FLAG_MMX },
	{ "psrld",   &Instruction::decode_Vo_Wo, OP_PSRLD,    FLAG_NONE },
	{ "psrlq",   &Instruction::decode_Vo_Wo, OP_PSRLQ,    FLAG_MMX },
	{ "paddq",   &Instruction::decode_Vo_Wo, OP_PADDQ,    FLAG_SSE2 },
	{ "pmullw",  &Instruction::decode_Vo_Wo, OP_PMULLW,   FLAG_MMX },
	{ "movq",    &Instruction::decode_Vo_Wo, OP_MOVQ,     FLAG_MMX },
	{ "pmovmskb",&Instruction::decode_Gd_Uo, OP_PMOVMSKB, FLAG_SSE },
    { "psubusb", &Instruction::decode_Vo_Wo, OP_PSUBUSB,  FLAG_MMX },
    { "psubusw", &Instruction::decode_Vo_Wo, OP_PSUBUSW,  FLAG_MMX },
    { "pminub",  &Instruction::decode_Vo_Wo, OP_PMINUB,   FLAG_SSE },
    { "pand",    &Instruction::decode_Vo_Wo, OP_PAND,     FLAG_MMX },
    { "paddusb", &Instruction::decode_Vo_Wo, OP_PADDUSB,  FLAG_MMX },
    { "paddusw", &Instruction::decode_Vo_Wo, OP_PADDUSW,  FLAG_MMX },
    { "pmaxub",  &Instruction::decode_Vo_Wo, OP_PMAXUB,   FLAG_SSE },
    { "pandn",   &Instruction::decode_Vo_Wo, OP_PANDN,    FLAG_MMX },

	/* 0x0f 0xe0 - 0x0f 0xef */
	{ "pavgb",     &Instruction::decode_Vo_Wo, OP_PAVGB,     FLAG_SSE },
	{ "psraw",     &Instruction::decode_Vo_Wo, OP_PSRAW,     FLAG_MMX },
	{ "psrad",     &Instruction::decode_Vo_Wo, OP_PSRAD,     FLAG_MMX },
	{ "pavgw",     &Instruction::decode_Vo_Wo, OP_PAVGW,     FLAG_SSE },
	{ "pmulhuw",   &Instruction::decode_Vo_Wo, OP_PMULHUW,   FLAG_SSE },
	{ "pmulhw",    &Instruction::decode_Vo_Wo, OP_PMULHW,    FLAG_MMX },
	{ "cvttpd2dq", &Instruction::decode_Vo_Wo, OP_CVTTPD2DQ, FLAG_SSE2 },
	{ "movntdq",   &Instruction::decode_Mo_Vo, OP_MOVNTDQ,   FLAG_SSE2 },
	{ "psubsb",    &Instruction::decode_Vo_Wo, OP_PSUBSB,    FLAG_MMX },
	{ "psubsw",    &Instruction::decode_Vo_Wo, OP_PSUBSW,    FLAG_MMX },
	{ "pminsw",    &Instruction::decode_Vo_Wo, OP_PMINSW,    FLAG_SSE },
	{ "por",       &Instruction::decode_Vo_Wo, OP_POR,       FLAG_MMX },
	{ "paddsb",    &Instruction::decode_Vo_Wo, OP_PADDSB,    FLAG_MMX },
	{ "paddsw",    &Instruction::decode_Vo_Wo, OP_PADDSW,    FLAG_MMX },
	{ "pmaxsw",    &Instruction::decode_Vo_Wo, OP_PMAXSW,    FLAG_SSE },
	{ "pxor",      &Instruction::decode_Vo_Wo, OP_PXOR,      FLAG_MMX },

	/* 0x0f 0xf0 - 0x0f 0xff */
	{ "invalid",    &Instruction::decode_invalid, OP_INVALID,       FLAG_NONE },
	{ "psllw",      &Instruction::decode_Vo_Wo,   OP_PSLLW,         FLAG_MMX },
	{ "pslld",      &Instruction::decode_Vo_Wo,   OP_PSLLD,         FLAG_MMX },
	{ "psllq",      &Instruction::decode_Vo_Wo,   OP_PSLLQ,         FLAG_MMX },
	{ "pmuludq",    &Instruction::decode_Vo_Wo,   OP_PMULUDQ,       FLAG_SSE2 },
	{ "pmaddwd",    &Instruction::decode_Vo_Wo,   OP_PMADDWD,       FLAG_MMX },
	{ "psadbw",     &Instruction::decode_Vo_Wo,   OP_PSADBW,        FLAG_SSE },
	{ "maskmovdqu", &Instruction::decode_Vo_Uo,   OP_MASKMOVDQU,    FLAG_SSE2 },
	{ "psubb",      &Instruction::decode_Vo_Wo,   OP_PSUBB,         FLAG_MMX },
	{ "psubw",      &Instruction::decode_Vo_Wo,   OP_PSUBW,         FLAG_MMX },
	{ "psubd",      &Instruction::decode_Vo_Wo,   OP_PSUBD,         FLAG_MMX },
	{ "psubq",      &Instruction::decode_Vo_Wo,   OP_PSUBQ,         FLAG_SSE2 },
	{ "paddb",      &Instruction::decode_Vo_Wo,   OP_PADDB,         FLAG_MMX },
	{ "paddw",      &Instruction::decode_Vo_Wo,   OP_PADDW,         FLAG_MMX },
	{ "paddd",      &Instruction::decode_Vo_Wo,   OP_PADDD,         FLAG_MMX },
	{ "invalid",    &Instruction::decode_invalid, OP_INVALID,       FLAG_NONE },
};

// 2 byte opcodes with a f2 prefix
template <class M>
const typename Instruction<M>::opcode_entry Instruction<M>::Opcodes_2Byte_F2[0x100] = {

	/* 0x0f 0x00 - 0x0f 0x0f */
	{ "group6", &Instruction::decode_group6, OP_GROUP, FLAG_NONE },
	{ "group7", &Instruction::decode_group7, OP_GROUP, FLAG_NONE },
	{ "lar",     &Instruction::decode_Gv_Ew,   OP_LAR,     FLAG_W_FLAGS },
	{ "lsl",     &Instruction::decode_Gv_Ew,   OP_LSL,     FLAG_W_FLAGS },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "clts", &Instruction::decode0, OP_CLTS, FLAG_W_FLAGS },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invd", &Instruction::decode0, OP_INVD, FLAG_NONE },
	{ "wbinvd", &Instruction::decode0, OP_WBINVD, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "ud2", &Instruction::decode0, OP_UD2, FLAG_PENTIUM_PRO },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "nop", &Instruction::decode_Ev, OP_NOP, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },

	/* 0x0f 0x10 - 0x0f 0x1f */
	{ "movsd",    &Instruction::decode_Vo_Wo,   OP_MOVSD,    FLAG_SSE2 },
	{ "movsd",    &Instruction::decode_Wo_Vo,   OP_MOVSD,    FLAG_SSE2 },
	{ "movddup",  &Instruction::decode_Vq_Mq,   OP_MOVDDUP,  FLAG_SSE3 },
	{ "movlps",   &Instruction::decode_Mq_Vq,   OP_MOVLPS,   FLAG_SSE },
	{ "unpcklps", &Instruction::decode_Vo_Wq,   OP_UNPCKLPS, FLAG_SSE },
	{ "unpckhps", &Instruction::decode_Vo_Wq,   OP_UNPCKHPS, FLAG_SSE },
	{ "movhps",   &Instruction::decode_Vq_Mq,   OP_MOVHPS,   FLAG_SSE },
	{ "movhps",   &Instruction::decode_Mq_Vq,   OP_MOVHPS,   FLAG_SSE },
	{ "group17",  &Instruction::decode_group17, OP_GROUP,    FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid, OP_INVALID,  FLAG_NONE },
	{ "nop",      &Instruction::decode_Ev,      OP_NOP,      FLAG_NONE }, // undocumented
	{ "invalid",  &Instruction::decode_invalid, OP_INVALID,  FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid, OP_INVALID,  FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid, OP_INVALID,  FLAG_NONE },
	{ "invalid",  &Instruction::decode_invalid, OP_INVALID,  FLAG_NONE },
	{ "nop",      &Instruction::decode_Ev,      OP_NOP,      FLAG_NONE },

	/* 0x0f 0x20 - 0x0f 0x2f */
	{ "mov", &Instruction::decode_Rd_Cd, OP_MOV, FLAG_R_FLAGS },
	{ "mov", &Instruction::decode_Rd_Dd, OP_MOV, FLAG_R_FLAGS },
	{ "mov", &Instruction::decode_Cd_Rd, OP_MOV, FLAG_R_FLAGS },
	{ "mov", &Instruction::decode_Dd_Rd, OP_MOV, FLAG_R_FLAGS },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "movaps", &Instruction::decode_Vo_Wo, OP_MOVAPS, FLAG_SSE },
	{ "movaps", &Instruction::decode_Wo_Vo, OP_MOVAPS, FLAG_SSE },
	{ "cvtsi2sd", &Instruction::decode_Vo_Ed, OP_CVTSI2SD, FLAG_SSE2 },    // x86-64: cvtsi2sd Vo, Eq
	{ "movntps",  &Instruction::decode_Mo_Vo, OP_MOVNTPS, FLAG_SSE },
	{ "cvttsd2si",  &Instruction::decode_Gd_Wo, OP_CVTTSD2SI, FLAG_SSE2 }, // x86-64: cvttsd2si Gq, Wo
	{ "cvtsd2si",  &Instruction::decode_Gd_Wo, OP_CVTSD2SI, FLAG_SSE2 },   // x86-64: cvtsd2si Gq, Wo
	{ "ucomiss",  &Instruction::decode_Vo_Wo, OP_UCOMISS, FLAG_SSE | FLAG_W_FLAGS },
	{ "comiss",  &Instruction::decode_Vo_Wo, OP_COMISS, FLAG_SSE | FLAG_W_FLAGS },

	/* 0x0f 0x30 - 0x0f 0x3f */
	{ "wrmsr", &Instruction::decode0, OP_WRMSR, FLAG_NONE },
	{ "rdtsc", &Instruction::decode0, OP_RDTSC, FLAG_NONE },
	{ "rdmsr", &Instruction::decode0, OP_RDMSR, FLAG_NONE },
	{ "rdpmc", &Instruction::decode0, OP_RDPMC, FLAG_NONE },
	{ "sysenter", &Instruction::decode0, OP_SYSENTER, FLAG_PENTIUM_PRO | FLAG_W_FLAGS },
	{ "sysexit", &Instruction::decode0, OP_SYSEXIT, FLAG_PENTIUM_PRO | FLAG_W_FLAGS },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "getsec", &Instruction::decode0, OP_GETSEC, FLAG_NONE },
	{ "3byte", &Instruction::decode_3byte_38, OP_3BYTE, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "3byte", &Instruction::decode_3byte_3A, OP_3BYTE, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },

	/* 0x0f 0x40 - 0x0f 0x4f */
	{ "cmovo",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovno",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovb",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnb",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovz",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnz",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovb",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnbe", &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovs",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovns",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovp",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnp",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovl",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnl",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovle",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnle", &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },

	/* 0x0f 0x50 - 0x0f 0x5f */
	{ "movmskps", &Instruction::decode_Gd_Uo, OP_MOVMSKPS, FLAG_SSE }, // x86-64: movmskps Gq, Uo
	{ "sqrtsd",   &Instruction::decode_Vo_Wo, OP_SQRTSD,   FLAG_SSE2 },
	{ "rsqrtps",  &Instruction::decode_Vo_Wo, OP_RSQRTPS,  FLAG_SSE },
	{ "rcpps",    &Instruction::decode_Vo_Wo, OP_RCPPS,    FLAG_SSE },
	{ "andps",    &Instruction::decode_Vo_Wo, OP_ANDPS,    FLAG_SSE },
	{ "andnps",   &Instruction::decode_Vo_Wo, OP_ANDNPS,   FLAG_SSE },
	{ "orps",     &Instruction::decode_Vo_Wo, OP_ORPS,     FLAG_SSE },
	{ "xorps",    &Instruction::decode_Vo_Wo, OP_XORPS,    FLAG_SSE },
	{ "addsd",    &Instruction::decode_Vo_Wo, OP_ADDSD,    FLAG_SSE2 },
	{ "mulsd",    &Instruction::decode_Vo_Wo, OP_MULSD,    FLAG_SSE2 },
	{ "cvtsd2ss", &Instruction::decode_Vo_Wo, OP_CVTSD2SS, FLAG_SSE2 },
	{ "cvtdq2ps", &Instruction::decode_Vo_Wo, OP_CVTDQ2PS, FLAG_SSE2 },
	{ "subsd",    &Instruction::decode_Vo_Wo, OP_SUBSD,    FLAG_SSE2 },
	{ "minsd",    &Instruction::decode_Vo_Wo, OP_MINSD,    FLAG_SSE2 },
	{ "divsd",    &Instruction::decode_Vo_Wo, OP_DIVSD,    FLAG_SSE2 },
	{ "maxsd",    &Instruction::decode_Vo_Wo, OP_MAXSD,    FLAG_SSE2 },

	/* 0x0f 0x60 - 0x0f 0x6f */
	{ "punpcklbw", &Instruction::decode_Pq_Qd, OP_PUNPCKLBW, FLAG_MMX },
	{ "punpcklwd", &Instruction::decode_Pq_Qd, OP_PUNPCKLWD, FLAG_MMX },
	{ "punpckldq", &Instruction::decode_Pq_Qd, OP_PUNPCKLDQ, FLAG_MMX },
	{ "packsswb", &Instruction::decode_Pq_Qq, OP_PACKSSWB, FLAG_MMX },
	{ "pcmpgtb", &Instruction::decode_Pq_Qq, OP_PCMPGTB, FLAG_MMX },
	{ "pcmpgtw", &Instruction::decode_Pq_Qq, OP_PCMPGTW, FLAG_MMX },
	{ "pcmpgtd", &Instruction::decode_Pq_Qq, OP_PCMPGTD, FLAG_MMX },
	{ "packuswb", &Instruction::decode_Pq_Qq, OP_PACKUSWB, FLAG_MMX },
	{ "punpckhbw", &Instruction::decode_Pq_Qd, OP_PUNPCKHBW, FLAG_MMX },
	{ "punpckhwd", &Instruction::decode_Pq_Qd, OP_PUNPCKHWD, FLAG_MMX },
	{ "punpckhdq", &Instruction::decode_Pq_Qd, OP_PUNPCKHDQ, FLAG_MMX },
	{ "packssdw", &Instruction::decode_Pq_Qq, OP_PACKSSDW, FLAG_MMX },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "movd", &Instruction::decode_Pd_Ed, OP_MOVD, FLAG_MMX }, // x86-64: movq Pd, Eq
	{ "movq", &Instruction::decode_Pq_Qq, OP_MOVQ, FLAG_MMX },

	/* 0x0f 0x70 - 0x0f 0x7f */
	{ "pshuflw", &Instruction::decode_Vo_Wo_Ib, OP_PSHUFLW, FLAG_SSE2 },
	{ "group13", &Instruction::decode_group13,  OP_GROUP,   FLAG_NONE },
	{ "group14", &Instruction::decode_group14,  OP_GROUP,   FLAG_NONE },
	{ "group15", &Instruction::decode_group15,  OP_GROUP,   FLAG_NONE },
	{ "pcmpeqb", &Instruction::decode_Pq_Qq,    OP_PCMPEQB, FLAG_MMX },
	{ "pcmpeqw", &Instruction::decode_Pq_Qq,    OP_PCMPEQW, FLAG_MMX },
	{ "pcmpeqd", &Instruction::decode_Pq_Qq,    OP_PCMPEQD, FLAG_MMX },
	{ "emms",    &Instruction::decode0,         OP_EMMS,    FLAG_MMX },
	{ "vmread",  &Instruction::decode_Ed_Gd,    OP_VMREAD,  FLAG_VMX | FLAG_W_FLAGS }, // x86-64: vmread Eq, Gq
	{ "vmwrite", &Instruction::decode_Gd_Ed,    OP_VMWRITE, FLAG_VMX | FLAG_W_FLAGS }, // x86-64: vmwrite Gq, Eq
	{ "invalid", &Instruction::decode_invalid,  OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid,  OP_INVALID, FLAG_NONE },
	{ "haddps",  &Instruction::decode_Vo_Wo,    OP_HADDPS,  FLAG_SSE3 },
	{ "hsubps",  &Instruction::decode_Vo_Wo,    OP_HSUBPS,  FLAG_SSE3 },
	{ "movd",    &Instruction::decode_Ed_Pd,    OP_MOVD,    FLAG_MMX }, // x86-64: movq Eq,Pd
	{ "movq",    &Instruction::decode_Qq_Pq,    OP_MOVQ,    FLAG_MMX },

	/* 0x0f 0x80 - 0x0f 0x8f */
	{ "jo",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jno",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jb",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnb",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jz",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnz",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jbe",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnbe", &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "js",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jns",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jp",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnp",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jl",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnl",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jle",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnle", &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },

	/* 0x0f 0x90 - 0x0f 0x9f */
	{ "seto",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setno",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setb",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnb",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setz",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnz",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setbe",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnbe", &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "sets",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setns",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setp",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnp",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setl",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnl",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setle",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnle", &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },

	/* 0x0f 0xa0 - 0x0f 0xaf */
	{ "push", &Instruction::decode_SegFS, OP_PUSH, FLAG_STACK },
	{ "pop", &Instruction::decode_SegFS, OP_POP, FLAG_STACK },
	{ "cpuid", &Instruction::decode0, OP_CPUID, FLAG_NONE },
	{ "bt", &Instruction::decode_Ev_Gv, OP_BT, FLAG_W_FLAGS },
	{ "shld", &Instruction::decode_Ev_Gv_Ib, OP_SHLD, FLAG_NONE },
	{ "shld", &Instruction::decode_Ev_Gv_CL, OP_SHLD, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "push", &Instruction::decode_SegGS, OP_PUSH, FLAG_STACK },
	{ "pop", &Instruction::decode_SegGS, OP_POP, FLAG_STACK },
	{ "rsm", &Instruction::decode0, OP_RSM, FLAG_NONE },
	{ "bts", &Instruction::decode_Ev_Gv, OP_BTS, FLAG_W_FLAGS },
	{ "shrd", &Instruction::decode_Ev_Gv_Ib, OP_SHRD, FLAG_NONE },
	{ "shrd", &Instruction::decode_Ev_Gv_CL, OP_SHRD, FLAG_NONE },
	{ "group16", &Instruction::decode_group16, OP_GROUP, FLAG_NONE },
	{ "imul",  &Instruction::decode_Gv_Ev, OP_IMUL, FLAG_W_FLAGS },

	/* 0x0f 0xb0 - 0x0f 0xbf */
	{ "cmpxchg", &Instruction::decode_Eb_Gb, OP_CMPXCHG, FLAG_W_FLAGS },
	{ "cmpxchg", &Instruction::decode_Ev_Gv, OP_CMPXCHG, FLAG_W_FLAGS },
	{ "lss", &Instruction::decode_Gv_Mp, OP_LSS, FLAG_NONE },
	{ "btr", &Instruction::decode_Ev_Gv, OP_BTR, FLAG_W_FLAGS },
	{ "lfs", &Instruction::decode_Gv_Mp, OP_LFS, FLAG_NONE },
	{ "lgs", &Instruction::decode_Gv_Mp, OP_LGS, FLAG_NONE },
	{ "movzx", &Instruction::decode_Gv_Eb, OP_MOVZX, FLAG_NONE },
	{ "movzx", &Instruction::decode_Gv_Ew, OP_MOVZX, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "group11", &Instruction::decode_group11, OP_GROUP, FLAG_NONE },
	{ "group8", &Instruction::decode_group8, OP_GROUP, FLAG_NONE },
	{ "btc", &Instruction::decode_Ev_Gv, OP_BTC, FLAG_W_FLAGS },
	{ "bsf", &Instruction::decode_Gv_Ev, OP_BSF, FLAG_W_FLAGS },
	{ "bsr", &Instruction::decode_Gv_Ev, OP_BSR, FLAG_W_FLAGS },
	{ "movsx", &Instruction::decode_Gv_Eb, OP_MOVSX, FLAG_NONE },
	{ "movsx", &Instruction::decode_Gv_Ew, OP_MOVSX, FLAG_NONE },

	/* 0x0f 0xc0 - 0x0f 0xcf */
	{ "xadd", &Instruction::decode_Eb_Gb, OP_XADD, FLAG_NONE },
	{ "xadd", &Instruction::decode_Ev_Gv, OP_XADD, FLAG_NONE },
	{ "cmpsd", &Instruction::decode_Vo_Wo_Ib, OP_CMPSD, FLAG_SSE2 },
	{ "movnti", &Instruction::decode_Md_Gd, OP_MOVNTI, FLAG_SSE2 },      // x86-64: movnti Nq, Gq
	{ "pinsrw", &Instruction::decode_Pq_Rd_Mw_Ib, OP_PINSRW, FLAG_SSE }, // x86-64: pinsrw Pq, Rq/Mw,Ib
	{ "pextrw", &Instruction::decode_Gd_Nq_Ib, OP_PEXTRW, FLAG_SSE | FLAG_SSE4_1 },
	{ "shufps", &Instruction::decode_Vo_Wo_Ib, OP_SHUFPS, FLAG_SSE },
	{ "group9", &Instruction::decode_group9, OP_GROUP, FLAG_NONE },
	{ "bswap", &Instruction::decode_rAX, OP_BSWAP, FLAG_NONE },
	{ "bswap", &Instruction::decode_rCX, OP_BSWAP, FLAG_NONE },
	{ "bswap", &Instruction::decode_rDX, OP_BSWAP, FLAG_NONE },
	{ "bswap", &Instruction::decode_rBX, OP_BSWAP, FLAG_NONE },
	{ "bswap", &Instruction::decode_rSP, OP_BSWAP, FLAG_NONE },
	{ "bswap", &Instruction::decode_rBP, OP_BSWAP, FLAG_NONE },
	{ "bswap", &Instruction::decode_rSI, OP_BSWAP, FLAG_NONE },
	{ "bswap", &Instruction::decode_rDI, OP_BSWAP, FLAG_NONE },

	/* 0x0f 0xd0 - 0x0f 0xdf */
	{ "addsubps", &Instruction::decode_Vo_Wo, OP_ADDSUBPS, FLAG_SSE3 },
	{ "psrlw", &Instruction::decode_Pq_Qq, OP_PSRLW, FLAG_MMX },
	{ "psrld", &Instruction::decode_Pq_Qq, OP_PSRLD, FLAG_NONE },
	{ "psrlq", &Instruction::decode_Pq_Qq, OP_PSRLQ, FLAG_MMX },
	{ "paddq", &Instruction::decode_Pq_Qq, OP_PADDQ, FLAG_SSE2 },
	{ "pmullw", &Instruction::decode_Pq_Qq, OP_PMULLW, FLAG_MMX },
	{ "movdq2q", &Instruction::decode_Pq_Qq, OP_MOVDQ2Q, FLAG_SSE2 },
	{ "pmovmskb", &Instruction::decode_Gd_Nq, OP_PMOVMSKB, FLAG_SSE },
    { "psubusb", &Instruction::decode_Pq_Qq, OP_PSUBUSB, FLAG_MMX },
    { "psubusw", &Instruction::decode_Pq_Qq, OP_PSUBUSW, FLAG_MMX },
    { "pminub", &Instruction::decode_Pq_Qq, OP_PMINUB, FLAG_SSE },
    { "pand", &Instruction::decode_Pq_Qq, OP_PAND, FLAG_MMX },
    { "paddusb", &Instruction::decode_Pq_Qq, OP_PADDUSB, FLAG_MMX },
    { "paddusw", &Instruction::decode_Pq_Qq, OP_PADDUSW, FLAG_MMX },
    { "pmaxub", &Instruction::decode_Pq_Qq, OP_PMAXUB, FLAG_SSE },
    { "pandn", &Instruction::decode_Pq_Qq, OP_PANDN, FLAG_MMX },

	/* 0x0f 0xe0 - 0x0f 0xef */
	{ "pavgb", &Instruction::decode_Pq_Qq, OP_PAVGB, FLAG_SSE },
	{ "psraw", &Instruction::decode_Pq_Qq, OP_PSRAW, FLAG_MMX },
	{ "psrad", &Instruction::decode_Pq_Qq, OP_PSRAD, FLAG_MMX },
	{ "pavgw", &Instruction::decode_Pq_Qq, OP_PAVGW, FLAG_SSE },
	{ "pmulhuw", &Instruction::decode_Pq_Qq, OP_PMULHUW, FLAG_SSE },
	{ "pmulhw", &Instruction::decode_Pq_Qq, OP_PMULHW, FLAG_MMX },
	{ "cvtpd2dq", &Instruction::decode_Vo_Wo, OP_CVTPD2DQ, FLAG_SSE2 },
	{ "movntq", &Instruction::decode_Mq_Pq, OP_MOVNTQ, FLAG_SSE },
	{ "psubsb", &Instruction::decode_Pq_Qq, OP_PSUBSB, FLAG_MMX },
	{ "psubsw", &Instruction::decode_Pq_Qq, OP_PSUBSW, FLAG_MMX },
	{ "pminsw", &Instruction::decode_Pq_Qq, OP_PMINSW, FLAG_SSE },
	{ "por", &Instruction::decode_Pq_Qq, OP_POR, FLAG_MMX },
	{ "paddsb", &Instruction::decode_Pq_Qq, OP_PADDSB, FLAG_MMX },
	{ "paddsw", &Instruction::decode_Pq_Qq, OP_PADDSW, FLAG_MMX },
	{ "pmaxsw", &Instruction::decode_Pq_Qq, OP_PMAXSW, FLAG_SSE },
	{ "pxor", &Instruction::decode_Pq_Qq, OP_PXOR, FLAG_MMX },

	/* 0x0f 0xf0 - 0x0f 0xff */
	{ "lddqu", &Instruction::decode_Vo_Mo, OP_LDDQU, FLAG_SSE3 },
	{ "psllw", &Instruction::decode_Pq_Qq, OP_PSLLW, FLAG_MMX },
	{ "pslld", &Instruction::decode_Pq_Qq, OP_PSLLD, FLAG_MMX },
	{ "psllq", &Instruction::decode_Pq_Qq, OP_PSLLQ, FLAG_MMX },
	{ "pmuludq", &Instruction::decode_Pq_Qq, OP_PMULUDQ, FLAG_SSE2 },
	{ "pmaddwd", &Instruction::decode_Pq_Qq, OP_PMADDWD, FLAG_MMX },
	{ "psadbw", &Instruction::decode_Pq_Qq, OP_PSADBW, FLAG_SSE },
	{ "maskmovq", &Instruction::decode_Pq_Nq, OP_MASKMOVQ, FLAG_SSE },
	{ "psubb", &Instruction::decode_Pq_Qq, OP_PSUBB, FLAG_MMX },
	{ "psubw", &Instruction::decode_Pq_Qq, OP_PSUBW, FLAG_MMX },
	{ "psubd", &Instruction::decode_Pq_Qq, OP_PSUBD, FLAG_MMX },
	{ "psubq", &Instruction::decode_Pq_Qq, OP_PSUBQ, FLAG_SSE2 },
	{ "paddb", &Instruction::decode_Pq_Qq, OP_PADDB, FLAG_MMX },
	{ "paddw", &Instruction::decode_Pq_Qq, OP_PADDW, FLAG_MMX },
	{ "paddd", &Instruction::decode_Pq_Qq, OP_PADDD, FLAG_MMX },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
};

// 2 byte opcodes with a f3 prefix
template <class M>
const typename Instruction<M>::opcode_entry Instruction<M>::Opcodes_2Byte_F3[0x100] = {

	/* 0x0f 0x00 - 0x0f 0x0f */
	{ "group6", &Instruction::decode_group6, OP_GROUP, FLAG_NONE },
	{ "group7", &Instruction::decode_group7, OP_GROUP, FLAG_NONE },
	{ "lar",     &Instruction::decode_Gv_Ew,   OP_LAR,     FLAG_W_FLAGS },
	{ "lsl",     &Instruction::decode_Gv_Ew,   OP_LSL,     FLAG_W_FLAGS },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "clts", &Instruction::decode0, OP_CLTS, FLAG_W_FLAGS },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invd", &Instruction::decode0, OP_INVD, FLAG_NONE },
	{ "wbinvd", &Instruction::decode0, OP_WBINVD, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "ud2", &Instruction::decode0, OP_UD2, FLAG_PENTIUM_PRO },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "nop", &Instruction::decode_Ev, OP_NOP, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },

	/* 0x0f 0x10 - 0x0f 0x1f */
	{ "movss", &Instruction::decode_Vo_Wo, OP_MOVSS, FLAG_SSE },
	{ "movss", &Instruction::decode_Wo_Vo, OP_MOVSS, FLAG_SSE },
	{ "movsldup", &Instruction::decode_Vq_Wq, OP_MOVSLDUP, FLAG_SSE3 },
	{ "movlps", &Instruction::decode_Mq_Vq, OP_MOVLPS, FLAG_SSE },
	{ "unpcklps", &Instruction::decode_Vo_Wq, OP_UNPCKLPS, FLAG_SSE },
	{ "unpckhps", &Instruction::decode_Vo_Wq, OP_UNPCKHPS, FLAG_SSE },
	{ "movshdup", &Instruction::decode_Vq_Wq, OP_MOVSHDUP, FLAG_SSE3 },
	{ "movhps", &Instruction::decode_Mq_Vq, OP_MOVHPS, FLAG_SSE },
	{ "group17", &Instruction::decode_group17, OP_GROUP, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "nop",      &Instruction::decode_Ev,      OP_NOP,      FLAG_NONE }, // undocumented
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "nop", &Instruction::decode_Ev, OP_NOP, FLAG_NONE },

	/* 0x0f 0x20 - 0x0f 0x2f */
	{ "mov", &Instruction::decode_Rd_Cd, OP_MOV, FLAG_R_FLAGS },
	{ "mov", &Instruction::decode_Rd_Dd, OP_MOV, FLAG_R_FLAGS },
	{ "mov", &Instruction::decode_Cd_Rd, OP_MOV, FLAG_R_FLAGS },
	{ "mov", &Instruction::decode_Dd_Rd, OP_MOV, FLAG_R_FLAGS },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "movaps", &Instruction::decode_Vo_Wo, OP_MOVAPS, FLAG_SSE },
	{ "movaps", &Instruction::decode_Wo_Vo, OP_MOVAPS, FLAG_SSE },
	{ "cvtsi2ss", &Instruction::decode_Vo_Ed, OP_CVTSI2SS, FLAG_SSE },    // x86-64: cvtsi2ss Vo, Eq
	{ "movntps",  &Instruction::decode_Mo_Vo, OP_MOVNTPS, FLAG_SSE },
	{ "cvttss2si",  &Instruction::decode_Gd_Wo, OP_CVTTSS2SI, FLAG_SSE }, // x86-64: cvttss2si Gq, Wo
	{ "cvtss2si",  &Instruction::decode_Gd_Wo, OP_CVTSS2SI, FLAG_SSE },   // x86-64: cvtss2si Gq, Wo
	{ "ucomiss",  &Instruction::decode_Vo_Wo, OP_UCOMISS, FLAG_SSE | FLAG_W_FLAGS },
	{ "comiss",  &Instruction::decode_Vo_Wo, OP_COMISS, FLAG_SSE | FLAG_W_FLAGS },

	/* 0x0f 0x30 - 0x0f 0x3f */
	{ "wrmsr", &Instruction::decode0, OP_WRMSR, FLAG_NONE },
	{ "rdtsc", &Instruction::decode0, OP_RDTSC, FLAG_NONE },
	{ "rdmsr", &Instruction::decode0, OP_RDMSR, FLAG_NONE },
	{ "rdpmc", &Instruction::decode0, OP_RDPMC, FLAG_NONE },
	{ "sysenter", &Instruction::decode0, OP_SYSENTER, FLAG_PENTIUM_PRO | FLAG_W_FLAGS },
	{ "sysexit", &Instruction::decode0, OP_SYSEXIT, FLAG_PENTIUM_PRO | FLAG_W_FLAGS },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "getsec", &Instruction::decode0, OP_GETSEC, FLAG_NONE },
	{ "3byte", &Instruction::decode_3byte_38, OP_3BYTE, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "3byte", &Instruction::decode_3byte_3A, OP_3BYTE, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },

	/* 0x0f 0x40 - 0x0f 0x4f */
	{ "cmovo",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovno",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovb",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnb",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovz",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnz",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovb",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnbe", &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovs",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovns",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovp",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnp",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovl",   &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnl",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovle",  &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },
	{ "cmovnle", &Instruction::decode_Gv_Ev, OP_CMOVCC, FLAG_R_FLAGS | FLAG_PENTIUM_PRO },

	/* 0x0f 0x50 - 0x0f 0x5f */
	{ "movmskps", &Instruction::decode_Gd_Uo, OP_MOVMSKPS, FLAG_SSE }, // x86-64: movmskps Gq, Uo
	{ "sqrtss", &Instruction::decode_Vo_Wo, OP_SQRTSS, FLAG_SSE },
	{ "rsqrtss", &Instruction::decode_Vo_Wo, OP_RSQRTSS, FLAG_SSE },
	{ "rcpss", &Instruction::decode_Vo_Wo, OP_RCPSS, FLAG_SSE },
	{ "andps", &Instruction::decode_Vo_Wo, OP_ANDPS, FLAG_SSE },
	{ "andnps", &Instruction::decode_Vo_Wo, OP_ANDNPS, FLAG_SSE },
	{ "orps", &Instruction::decode_Vo_Wo, OP_ORPS, FLAG_SSE },
	{ "xorps", &Instruction::decode_Vo_Wo, OP_XORPS, FLAG_SSE },
	{ "addss", &Instruction::decode_Vo_Wo, OP_ADDSS, FLAG_SSE },
	{ "mulss", &Instruction::decode_Vo_Wo, OP_MULSS, FLAG_SSE },
	{ "cvtss2sd", &Instruction::decode_Vo_Wo, OP_CVTSS2SD, FLAG_SSE2 },
	{ "cvttps2dq", &Instruction::decode_Vo_Wo, OP_CVTTPS2DQ, FLAG_SSE2 },
	{ "subss", &Instruction::decode_Vo_Wo, OP_SUBSS, FLAG_SSE },
	{ "minss", &Instruction::decode_Vo_Wo, OP_MINSS, FLAG_SSE },
	{ "divss", &Instruction::decode_Vo_Wo, OP_DIVSS, FLAG_SSE },
	{ "maxss", &Instruction::decode_Vo_Wo, OP_MAXSS, FLAG_SSE },

	/* 0x0f 0x60 - 0x0f 0x6f */
	{ "punpcklbw", &Instruction::decode_Pq_Qd,   OP_PUNPCKLBW, FLAG_MMX },
	{ "punpcklwd", &Instruction::decode_Pq_Qd,   OP_PUNPCKLWD, FLAG_MMX },
	{ "punpckldq", &Instruction::decode_Pq_Qd,   OP_PUNPCKLDQ, FLAG_MMX },
	{ "packsswb",  &Instruction::decode_Pq_Qq,   OP_PACKSSWB,  FLAG_MMX },
	{ "pcmpgtb",   &Instruction::decode_Pq_Qq,   OP_PCMPGTB,   FLAG_MMX },
	{ "pcmpgtw",   &Instruction::decode_Pq_Qq,   OP_PCMPGTW,   FLAG_MMX },
	{ "pcmpgtd",   &Instruction::decode_Pq_Qq,   OP_PCMPGTD,   FLAG_MMX },
	{ "packuswb",  &Instruction::decode_Pq_Qq,   OP_PACKUSWB,  FLAG_MMX },
	{ "punpckhbw", &Instruction::decode_Pq_Qd,   OP_PUNPCKHBW, FLAG_MMX },
	{ "punpckhwd", &Instruction::decode_Pq_Qd,   OP_PUNPCKHWD, FLAG_MMX },
	{ "punpckhdq", &Instruction::decode_Pq_Qd,   OP_PUNPCKHDQ, FLAG_MMX },
	{ "packssdw",  &Instruction::decode_Pq_Qq,   OP_PACKSSDW,  FLAG_MMX },
	{ "invalid",   &Instruction::decode_invalid, OP_INVALID,   FLAG_NONE },
	{ "invalid",   &Instruction::decode_invalid, OP_INVALID,   FLAG_NONE },
	{ "movd",      &Instruction::decode_Pd_Ed,   OP_MOVD,      FLAG_MMX }, // x86-64: movq Pd, Eq
	{ "movdqu",    &Instruction::decode_Vo_Wo,   OP_MOVDQU,    FLAG_SSE2 },

	/* 0x0f 0x70 - 0x0f 0x7f */
	{ "pshufhw", &Instruction::decode_Vo_Wo_Ib, OP_PSHUFHW, FLAG_SSE2 },
	{ "group13", &Instruction::decode_group13, OP_GROUP, FLAG_NONE },
	{ "group14", &Instruction::decode_group14, OP_GROUP, FLAG_NONE },
	{ "group15", &Instruction::decode_group15, OP_GROUP, FLAG_NONE },
	{ "pcmpeqb", &Instruction::decode_Pq_Qq, OP_PCMPEQB, FLAG_MMX },
	{ "pcmpeqw", &Instruction::decode_Pq_Qq, OP_PCMPEQW, FLAG_MMX },
	{ "pcmpeqd", &Instruction::decode_Pq_Qq, OP_PCMPEQD, FLAG_MMX },
	{ "emms",    &Instruction::decode0, OP_EMMS, FLAG_MMX },
	{ "vmread",  &Instruction::decode_Ed_Gd, OP_VMREAD, FLAG_VMX | FLAG_W_FLAGS },  // x86-64: vmread Eq, Gq
	{ "vmwrite", &Instruction::decode_Gd_Ed, OP_VMWRITE, FLAG_VMX | FLAG_W_FLAGS }, // x86-64: vmwrite Gq, Eq
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "movq",    &Instruction::decode_Vq_Wq, OP_MOVQ, FLAG_MMX },
	{ "movdqu",  &Instruction::decode_Wo_Vo, OP_MOVDQU, FLAG_SSE2 },

	/* 0x0f 0x80 - 0x0f 0x8f */
	{ "jo",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jno",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jb",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnb",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jz",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnz",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jbe",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnbe", &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "js",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jns",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jp",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnp",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jl",   &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnl",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jle",  &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },
	{ "jnle", &Instruction::decode_Jz, OP_JCC, FLAG_R_FLAGS },

	/* 0x0f 0x90 - 0x0f 0x9f */
	{ "seto",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setno",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setb",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnb",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setz",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnz",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setbe",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnbe", &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "sets",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setns",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setp",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnp",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setl",   &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnl",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setle",  &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },
	{ "setnle", &Instruction::decode_Eb, OP_SETCC, FLAG_R_FLAGS },

	/* 0x0f 0xa0 - 0x0f 0xaf */
	{ "push", &Instruction::decode_SegFS, OP_PUSH, FLAG_STACK },
	{ "pop", &Instruction::decode_SegFS, OP_POP, FLAG_STACK },
	{ "cpuid", &Instruction::decode0, OP_CPUID, FLAG_NONE },
	{ "bt", &Instruction::decode_Ev_Gv, OP_BT, FLAG_W_FLAGS },
	{ "shld", &Instruction::decode_Ev_Gv_Ib, OP_SHLD, FLAG_NONE },
	{ "shld", &Instruction::decode_Ev_Gv_CL, OP_SHLD, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "push", &Instruction::decode_SegGS, OP_PUSH, FLAG_STACK },
	{ "pop", &Instruction::decode_SegGS, OP_POP, FLAG_STACK },
	{ "rsm", &Instruction::decode0, OP_RSM, FLAG_NONE },
	{ "bts", &Instruction::decode_Ev_Gv, OP_BTS, FLAG_W_FLAGS },
	{ "shrd", &Instruction::decode_Ev_Gv_Ib, OP_SHRD, FLAG_NONE },
	{ "shrd", &Instruction::decode_Ev_Gv_CL, OP_SHRD, FLAG_NONE },
	{ "group16", &Instruction::decode_group16, OP_GROUP, FLAG_NONE },
	{ "imul",  &Instruction::decode_Gv_Ev, OP_IMUL, FLAG_W_FLAGS },

	/* 0x0f 0xb0 - 0x0f 0xbf */
	{ "cmpxchg", &Instruction::decode_Eb_Gb, OP_CMPXCHG, FLAG_W_FLAGS },
	{ "cmpxchg", &Instruction::decode_Ev_Gv, OP_CMPXCHG, FLAG_W_FLAGS },
	{ "lss", &Instruction::decode_Gv_Mp, OP_LSS, FLAG_NONE },
	{ "btr", &Instruction::decode_Ev_Gv, OP_BTR, FLAG_W_FLAGS },
	{ "lfs", &Instruction::decode_Gv_Mp, OP_LFS, FLAG_NONE },
	{ "lgs", &Instruction::decode_Gv_Mp, OP_LGS, FLAG_NONE },
	{ "movzx", &Instruction::decode_Gv_Eb, OP_MOVZX, FLAG_NONE },
	{ "movzx", &Instruction::decode_Gv_Ew, OP_MOVZX, FLAG_NONE },
	{ "popcnt", &Instruction::decode_Gv_Ev, OP_POPCNT, FLAG_SSE4a },
	{ "group11", &Instruction::decode_group11, OP_GROUP, FLAG_NONE },
	{ "group8", &Instruction::decode_group8, OP_GROUP, FLAG_NONE },
	{ "btc", &Instruction::decode_Ev_Gv, OP_BTC, FLAG_W_FLAGS },
	{ "bsf", &Instruction::decode_Gv_Ev, OP_BSF, FLAG_W_FLAGS },
	{ "bsr", &Instruction::decode_Gv_Ev, OP_BSR, FLAG_W_FLAGS },
	{ "movsx", &Instruction::decode_Gv_Eb, OP_MOVSX, FLAG_NONE },
	{ "movsx", &Instruction::decode_Gv_Ew, OP_MOVSX, FLAG_NONE },

	/* 0x0f 0xc0 - 0x0f 0xcf */
	{ "xadd", &Instruction::decode_Eb_Gb, OP_XADD, FLAG_NONE },
	{ "xadd", &Instruction::decode_Ev_Gv, OP_XADD, FLAG_NONE },
	{ "cmpss", &Instruction::decode_Vo_Wo_Ib, OP_CMPSS, FLAG_SSE },
	{ "movnti", &Instruction::decode_Md_Gd, OP_MOVNTI, FLAG_SSE2 },       // x86-64: movnti Nq, Gq
	{ "pinsrw", &Instruction::decode_Pq_Rd_Mw_Ib, OP_PINSRW, FLAG_SSE },  // x86-64: pinsrw Pq, Rq/Mw,Ib
	{ "pextrw", &Instruction::decode_Gd_Nq_Ib, OP_PEXTRW, FLAG_SSE | FLAG_SSE4_1 },
	{ "shufps", &Instruction::decode_Vo_Wo_Ib, OP_SHUFPS, FLAG_SSE },
	{ "group9", &Instruction::decode_group9, OP_GROUP, FLAG_NONE },
	{ "bswap", &Instruction::decode_rAX, OP_BSWAP, FLAG_NONE },
	{ "bswap", &Instruction::decode_rCX, OP_BSWAP, FLAG_NONE },
	{ "bswap", &Instruction::decode_rDX, OP_BSWAP, FLAG_NONE },
	{ "bswap", &Instruction::decode_rBX, OP_BSWAP, FLAG_NONE },
	{ "bswap", &Instruction::decode_rSP, OP_BSWAP, FLAG_NONE },
	{ "bswap", &Instruction::decode_rBP, OP_BSWAP, FLAG_NONE },
	{ "bswap", &Instruction::decode_rSI, OP_BSWAP, FLAG_NONE },
	{ "bswap", &Instruction::decode_rDI, OP_BSWAP, FLAG_NONE },

	/* 0x0f 0xd0 - 0x0f 0xdf */
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "psrlw", &Instruction::decode_Pq_Qq, OP_PSRLW, FLAG_MMX },
	{ "psrld", &Instruction::decode_Pq_Qq, OP_PSRLD, FLAG_NONE },
	{ "psrlq", &Instruction::decode_Pq_Qq, OP_PSRLQ, FLAG_MMX },
	{ "paddq", &Instruction::decode_Pq_Qq, OP_PADDQ, FLAG_SSE2 },
	{ "pmullw", &Instruction::decode_Pq_Qq, OP_PMULLW, FLAG_MMX },
	{ "movq2dq", &Instruction::decode_Vo_Nq, OP_MOVQ2DQ, FLAG_SSE2 },
	{ "pmovmskb", &Instruction::decode_Gd_Nq, OP_PMOVMSKB, FLAG_SSE },
    { "psubusb", &Instruction::decode_Pq_Qq, OP_PSUBUSB, FLAG_MMX },
    { "psubusw", &Instruction::decode_Pq_Qq, OP_PSUBUSW, FLAG_MMX },
    { "pminub", &Instruction::decode_Pq_Qq, OP_PMINUB, FLAG_SSE },
    { "pand", &Instruction::decode_Pq_Qq, OP_PAND, FLAG_MMX },
    { "paddusb", &Instruction::decode_Pq_Qq, OP_PADDUSB, FLAG_MMX },
    { "paddusw", &Instruction::decode_Pq_Qq, OP_PADDUSW, FLAG_MMX },
    { "pmaxub", &Instruction::decode_Pq_Qq, OP_PMAXUB, FLAG_SSE },
    { "pandn", &Instruction::decode_Pq_Qq, OP_PANDN, FLAG_MMX },

	/* 0x0f 0xe0 - 0x0f 0xef */
	{ "pavgb", &Instruction::decode_Pq_Qq, OP_PAVGB, FLAG_SSE },
	{ "psraw", &Instruction::decode_Pq_Qq, OP_PSRAW, FLAG_MMX },
	{ "psrad", &Instruction::decode_Pq_Qq, OP_PSRAD, FLAG_MMX },
	{ "pavgw", &Instruction::decode_Pq_Qq, OP_PAVGW, FLAG_SSE },
	{ "pmulhuw", &Instruction::decode_Pq_Qq, OP_PMULHUW, FLAG_SSE },
	{ "pmulhw", &Instruction::decode_Pq_Qq, OP_PMULHW, FLAG_MMX },
	{ "cvtdq2pd", &Instruction::decode_Vo_Wo, OP_CVTDQ2PD, FLAG_SSE2 },
	{ "movntq", &Instruction::decode_Mq_Pq, OP_MOVNTQ, FLAG_SSE },
	{ "psubsb", &Instruction::decode_Pq_Qq, OP_PSUBSB, FLAG_MMX },
	{ "psubsw", &Instruction::decode_Pq_Qq, OP_PSUBSW, FLAG_MMX },
	{ "pminsw", &Instruction::decode_Pq_Qq, OP_PMINSW, FLAG_SSE },
	{ "por", &Instruction::decode_Pq_Qq, OP_POR, FLAG_MMX },
	{ "paddsb", &Instruction::decode_Pq_Qq, OP_PADDSB, FLAG_MMX },
	{ "paddsw", &Instruction::decode_Pq_Qq, OP_PADDSW, FLAG_MMX },
	{ "pmaxsw", &Instruction::decode_Pq_Qq, OP_PMAXSW, FLAG_SSE },
	{ "pxor", &Instruction::decode_Pq_Qq, OP_PXOR, FLAG_MMX },

	/* 0x0f 0xf0 - 0x0f 0xff */
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
	{ "psllw", &Instruction::decode_Pq_Qq, OP_PSLLW, FLAG_MMX },
	{ "pslld", &Instruction::decode_Pq_Qq, OP_PSLLD, FLAG_MMX },
	{ "psllq", &Instruction::decode_Pq_Qq, OP_PSLLQ, FLAG_MMX },
	{ "pmuludq", &Instruction::decode_Pq_Qq, OP_PMULUDQ, FLAG_SSE2 },
	{ "pmaddwd", &Instruction::decode_Pq_Qq, OP_PMADDWD, FLAG_MMX },
	{ "psadbw", &Instruction::decode_Pq_Qq, OP_PSADBW, FLAG_SSE },
	{ "maskmovq", &Instruction::decode_Pq_Nq, OP_MASKMOVQ, FLAG_SSE },
	{ "psubb", &Instruction::decode_Pq_Qq, OP_PSUBB, FLAG_MMX },
	{ "psubw", &Instruction::decode_Pq_Qq, OP_PSUBW, FLAG_MMX },
	{ "psubd", &Instruction::decode_Pq_Qq, OP_PSUBD, FLAG_MMX },
	{ "psubq", &Instruction::decode_Pq_Qq, OP_PSUBQ, FLAG_SSE2 },
	{ "paddb", &Instruction::decode_Pq_Qq, OP_PADDB, FLAG_MMX },
	{ "paddw", &Instruction::decode_Pq_Qq, OP_PADDW, FLAG_MMX },
	{ "paddd", &Instruction::decode_Pq_Qq, OP_PADDD, FLAG_MMX },
	{ "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
};

}

#endif
